<?php

declare(strict_types=1);

namespace App\Controller\Admin;

use App\Constants\ErrorCode;
use App\Model\Admin\Admin;
use App\Model\ChargeOption;
use App\Model\Device;
use App\Model\Order;
use App\Model\Station;
use Hyperf\DbConnection\Db;
use Hyperf\Redis\Redis;
use Hyperf\HttpServer\Contract\RequestInterface;
use PhpOffice\PhpSpreadsheet\Spreadsheet;
use PhpOffice\PhpSpreadsheet\Writer\Xlsx;
use Psr\Container\ContainerExceptionInterface;
use Psr\Container\NotFoundExceptionInterface;
use Psr\Http\Message\ResponseInterface;
use Psr\SimpleCache\InvalidArgumentException;
use RedisException;
use Trait\ResponseMsg;
use App\Model\Normal;
use Hyperf\Di\Annotation\Inject;
use Util\Common;
use App\Controller\AbstractController;
use App\Model\Distributors;

class StationController extends AbstractController
{
    use ResponseMsg;

    protected Redis $redis;
    protected Normal $normal;

    #[Inject]
    protected Station $station;

    #[Inject]
    protected Admin $admin;

    #[Inject]
    protected ChargeOption $chargeOption;

    #[Inject]
    protected Distributors $distributors;

    #[Inject]
    protected Device $device;

    public function __construct()
    {
        $this->redis = container()->get(Redis::class);
        $this->normal = container()->get(Normal::class);
    }

    /**电站列表
     * @param RequestInterface $request
     * @return ResponseInterface
     * @throws ContainerExceptionInterface
     * @throws NotFoundExceptionInterface
     */
    public function getList(RequestInterface $request): ResponseInterface
    {
        $page = $request->inputs(['page', 'limit', 'keyword','province_code',
            'city_code','area_code','distributor_id', 'class_id']);
        $page['info'] = $this->admin->getInfo($request);
        $model = $this->station->where(function ($query) use ($page) {
            if (array_key_exists('keyword', $page) && $page['keyword']) {
                $query->where('name', 'like', '%' . $page['keyword'] . '%');
                $query->orWhere('address', 'like', '%' . $page['keyword'] . '%');
            }
            if ($page['class_id'] != '') {
                $query->where('class_id', $page['class_id']);
            }
            if ($page['distributor_id']) {
                $query->where('distributor_id', $page['distributor_id']);
            }
            if ($page['distributor_id']) {
                $query->where('distributor_id', $page['distributor_id']);
            }else{
                if($page['info']['type'] == Admin::TYPE_USER){
                    $query->where('distributor_id',$page['info']['distributor_id']);
                }
            }
            if(isset($page['province_code']) && $page['province_code']){
                $query->where('province_code', $page['province_code']);
            }
            if(isset($page['city_code']) && $page['city_code']){
                $query->where('city_code', $page['city_code']);
            }
            if(isset($page['area_code']) && $page['area_code']){
                $query->where('area_code', $page['area_code']);
            }
        });
        $data['total'] = $model->count();
        $data['list'] = $model->withCount('device as device_count')
            ->with(['distributor' => function($query) {
                $query->select('id', 'name'); // 只获取经销商id和name
            }])
            ->with('stationClass')
            ->with('charge')
            ->orderBy('id', 'desc')
            ->offset(($page['page'] - 1) * $page['limit'])
            ->limit($page['limit'])
            ->get();
        return $this->success($data);
    }

    /**下拉菜单-套餐
     * @param RequestInterface $request
     * @return ResponseInterface
     * @throws ContainerExceptionInterface
     * @throws NotFoundExceptionInterface
     */
    public function selectCharge(RequestInterface $request): ResponseInterface
    {
        $distributor_id = $request->input('distributor_id');
        $list = $this->chargeOption->where('distributor_id', 0)
            ->where('is_del', Common::DEL_SHOW)
            ->orderBy('sort', 'desc')
            ->get(['id', 'name'])->toArray();
        foreach ($list as $k => $v) {
            $list[$k]['name'] = '[默认]' . $v['name'];
        }
        if ($distributor_id) {
            $dis_list = $this->chargeOption->where('distributor_id', $distributor_id)
                ->where('is_del', Common::DEL_SHOW)
                ->orderBy('sort', 'desc')
                ->get(['id', 'name'])->toArray();
            $list = array_merge($list, $dis_list);
        }
        return $this->success($list);
    }

    /**下拉菜单充电桩
     * @param RequestInterface $request
     * @return ResponseInterface
     * @throws ContainerExceptionInterface
     * @throws NotFoundExceptionInterface
     */
    public function selectStation(RequestInterface $request): ResponseInterface
    {
        $distributor_id = $request->input('distributor_id');

        if (!$distributor_id) {
            return $this->error(code: 1001, msg: '请先选择经销商');
        }
        $list = $this->station->where('distributor_id', $distributor_id)
            ->get(['id', 'name'])->toArray();
        return $this->success($list);
    }

    public function classStation(RequestInterface $request): ResponseInterface
    {
        $class_id = $request->input('class_id');
        if (!$class_id) {
            return $this->error(code: 1001, msg: '请选择分类id');
        }
        $list = $this->station->where('class_id', $class_id)
            ->where('class_id', $class_id)
            ->get(['id', 'name'])->toArray();
        return $this->success($list);
    }

    /**修改状态
     * @param RequestInterface $request
     * @return ResponseInterface
     * @throws ContainerExceptionInterface
     * @throws NotFoundExceptionInterface
     */
    public function changeStatus(RequestInterface $request): ResponseInterface
    {
        $status = $request->input('status', 0, 'int');
        $id = $request->input('id', 0, 'int');
        if (!$id) {
            return $this->error(code: 1001, msg: '缺失参数id');
        }
        $this->station->where('id', $id)->update(['is_active' => $status]);
        return $this->success(msg: '修改成功');
    }


    /**获取经销商id
     * @param RequestInterface $request
     * @return ResponseInterface
     * @throws ContainerExceptionInterface
     * @throws NotFoundExceptionInterface
     */
    public function getDistributor(RequestInterface $request): ResponseInterface
    {
        $station_id = $request->input('station_id', 0, 'int');
        $distributorId = $this->station->where('id', $station_id)->first(['distributor_id']);
        return $this->success($distributorId);
    }


    /**创建电站
     * @param RequestInterface $request
     * @return ResponseInterface
     * @throws ContainerExceptionInterface
     * @throws NotFoundExceptionInterface
     */
    public function create(RequestInterface $request): ResponseInterface
    {
        try {
            $data = $request->post();
            if (array_key_exists('id', $data) && $data['id'] > 0) {
                $id = $data['id'];
                unset($data['id']);
                $station = $this->station->where('id', $id)->first();
                $distributor = Distributors::where('id', $data['distributor_id'])->first();
                if (!$distributor) {
                    return $this->error(1001, '经销商不存在或未选择经销商');
                }
                if ($station->distributor_id != $data['distributor_id']) {
                    $device['distributor_id'] = $distributor->id;
                    $this->device->where('station_id', $id)->update($device);
                }
                $this->station->where('id', $id)->update($data);
            } else {
                $station = Station::create($data);
            }
            Device::removeStation($station->id . '');
            Device::addStation($station->id . '', (float)$station->lng, (float)$station->lat);
            return $this->success();
        } catch (\Exception $e) {
            return $this->error(code: 1001, msg: $e->getMessage() . $e->getTraceAsString());
        }
    }

    /**删除充电站
     * @param RequestInterface $request
     * @return ResponseInterface
     * @throws ContainerExceptionInterface
     * @throws NotFoundExceptionInterface
     */
    public function del(RequestInterface $request): ResponseInterface
    {
        $id = $request->input('station_id', 0, 'int');
        if (!$id) {
            return $this->error(ErrorCode::PARAMS_ERR);
        }
        $this->station->where('id', $id)->delete();
        $this->device->where('station_id', $id)->update(['station_id' => 0]);
        return $this->success();
    }

    /**
     * 收款统计
     * @param RequestInterface $request
     * @return ResponseInterface
     * @throws ContainerExceptionInterface
     * @throws NotFoundExceptionInterface
     */
    public function moneyTotal(RequestInterface $request): ResponseInterface
    {
        $params = $request->inputs(['class_id', 'station_id', 'time']);
        if (!isset($params['station_id']) || count($params['station_id']) <= 0) {
            $params['station_id'] = Station::where('class_id', $params['class_id'])->pluck('id')->toArray();
        }
        $data = [];
        // 循环统计
        foreach ($params['station_id'] as $val) {
            $order = Order::where(function ($query) use ($params, $val) {
                if ($params['station_id']) {
                    $query->where('station_id', $val);
                }
                if (isset($params['time']) && is_array($params['time'])) {
                    $query->where('created_at', '>=', $params['time'][0]);
                    $query->where('created_at', '<=', $params['time'][1]);
                }
            })->whereIn('status', [Order::STATUS_END, Order::STATUS_REFUNDED])->get();
            // 电站电单价
            $station = Station::where('id', $val)->first();
            $temp['station_id'] = $val;
            $temp['name'] = $station['name'];
            // 总金额
            $temp['total'] = round($order->sum('fee'), 2);// 总计

            // 总退款金额
            $temp['return_fee'] = round($order->sum('return_fee'), 2);// 总计
            // 电站电价成本
            $use_elec = $order->sum('use_elec');
            $temp['power_total'] = round($use_elec > 0 ? $use_elec / 1000 : 0, 3);
            $temp['power_price'] = round($station['local_fee'] * $temp['power_total'], 2);
            //电费
            $temp['use_fee'] = $order->sum('use_fee');
            // 服务费
            $temp['charge_service'] = round($order->sum('charge_service'), 2);
            // 总优惠券金额
            $temp['coupon'] = $order->sum('power_fee') - $order->sum('fee');
            // 单量
            $temp['order_total'] = $order->count();
            $temp['diff'] = $temp['total'] - $temp['return_fee'];
            $data[] = $temp;
        }
        return $this->success($data);
    }

    public function exportTotal(RequestInterface $request)
    {
        $params = $request->inputs(['class_id', 'station_id', 'time']);
        if (!isset($params['station_id']) || count($params['station_id']) <= 0) {
            $params['station_id'] = Station::where('class_id', $params['class_id'])->pluck('id')->toArray();
        }
        $data = [];
        // 循环统计
        foreach ($params['station_id'] as $val) {
            $order = Order::where(function ($query) use ($params, $val) {
                if ($params['station_id']) {
                    $query->where('station_id', $val);
                }
                if (isset($params['time']) && is_array($params['time'])) {
                    $query->where('created_at', '>=', $params['time'][0]);
                    $query->where('created_at', '<=', $params['time'][1]);
                }
            })->whereIn('status', [Order::STATUS_END, Order::STATUS_REFUNDED])->get();
            // 电站电单价
            $station = Station::where('id', $val)->first();
            $temp['station_id'] = $val;
            $temp['name'] = $station['name'];
            // 总金额
            $temp['total'] = round($order->sum('fee'), 2);// 总计

            // 总退款金额
            $temp['return_fee'] = round($order->sum('return_fee'), 2);// 总计
            // 电站电价成本
            $use_elec = $order->sum('use_elec');
            $temp['power_total'] = round($use_elec > 0 ? $use_elec / 1000 : 0, 3);
            $temp['power_price'] = round($station['local_fee'] * $temp['power_total'], 2);
            //电费
            $temp['use_fee'] = $order->sum('use_fee');
            // 服务费
            $temp['charge_service'] = round($order->sum('charge_service'), 2);
            // 总优惠券金额
            $temp['coupon'] = $order->sum('power_fee') - $order->sum('fee');
            // 单量
            $temp['order_total'] = $order->count();
            $temp['diff'] = $temp['total'] - $temp['return_fee'];
            $data[] = $temp;
        }
        $spreadsheet = new Spreadsheet();
        $sheet = $spreadsheet->getActiveSheet();
        // 设置 Excel 文档的头部
        $sheet->setCellValue('A1', '电站名称');
        $sheet->setCellValue('B1', '实收金额/元');
        $sheet->setCellValue('C1', '退款金额/元');
        $sheet->setCellValue('D1', '电站电费成本');
        $sheet->setCellValue('E1', '使用电费');
        $sheet->setCellValue('F1', '服务费');
        $sheet->setCellValue('G1', '已抵扣金额');
        $sheet->setCellValue('H1', '订单量');
        $sheet->setCellValue('I1', '总用电量');
        $sheet->setCellValue('J1', '实际收入');
        foreach (range('A', 'O') as $columnID) {
            $sheet->getColumnDimension($columnID)->setAutoSize(true);
        }

// 设置单元格水平居中的样式数组配置
        $styleArray = [
            'alignment' => [
                'horizontal' => \PhpOffice\PhpSpreadsheet\Style\Alignment::HORIZONTAL_CENTER,
            ],
        ];

        $sheet->getStyle('A:O')->applyFromArray($styleArray);
        // 从第二行开始填充订单数据
        $row = 2;
        foreach ($data as $station) {
            $sheet->setCellValue('A' . $row, $station['name']);
            $sheet->setCellValue('B' . $row, $station['total']);
            $sheet->setCellValue('C' . $row, $station['return_fee']);
            $sheet->setCellValue('D' . $row, $station['power_price']);
            $sheet->setCellValue('E' . $row, $station['use_fee']);
            $sheet->setCellValue('F' . $row, $station['charge_service']);
            $sheet->setCellValue('G' . $row, $station['coupon']);
            $sheet->setCellValue('H' . $row, $station['order_total']);
            $sheet->setCellValue('I' . $row, $station['power_total']);
            $sheet->setCellValue('J' . $row, $station['diff']);
            $row++;
        }
        // 将 Spreadsheet 对象写入 XLSX 文件
        $writer = new Xlsx($spreadsheet);
        // 创建临时文件
        $publicPath = BASE_PATH . '/public/upload/xls/';
        $fileName = date('YmdHis', time()) . '-stations.xlsx';
//        $temp_file = tempnam(sys_get_temp_dir(), $fileName);
        $temp_file = $publicPath . $fileName;
        // 保存到临时文件
        $writer->save($temp_file);
        return $this->success(['url' => Common::MAIN_HOST . '/upload/xls/' . $fileName]);
    }

    /**
     * 订单统计
     * @param RequestInterface $request
     * @return ResponseInterface
     * @throws ContainerExceptionInterface
     * @throws NotFoundExceptionInterface
     */
    public function orderTotal(RequestInterface $request): ResponseInterface
    {
        $params = $request->inputs(['station_id', 'time']);
        $data = [];
        // 循环统计
        foreach ($params['station_id'] as $val) {
            $order_total = Order::where(function ($query) use ($params, $val) {
                if ($params['station_id']) {
                    $query->where('station_id', $val);
                }
                if (isset($params['time']) && is_array($params['time'])) {
                    $query->where('created_at', '>=', $params['time'][0]);
                    $query->where('created_at', '<=', $params['time'][1]);
                }
            })->count();
            $station = Station::where('id', $val)->first();
            $temp['station_id'] = $val;
            $temp['name'] = $station['name'];
            // 累计单量
            $temp['order_total'] = $order_total;
            $data[] = $temp;
        }
        return $this->success($data);
    }

    /**
     * 充电量统计
     * @param RequestInterface $request
     * @return ResponseInterface
     * @throws ContainerExceptionInterface
     * @throws NotFoundExceptionInterface
     */
    public function powerTotal(RequestInterface $request): ResponseInterface
    {
        $params = $request->inputs(['station_id', 'time']);
        $data = [];
        // 循环统计
        foreach ($params['station_id'] as $val) {
            $use_elec = Order::where(function ($query) use ($params, $val) {
                if ($params['station_id']) {
                    $query->where('station_id', $val);
                }
                if (isset($params['time']) && is_array($params['time'])) {
                    $query->where('created_at', '>=', $params['time'][0]);
                    $query->where('created_at', '<=', $params['time'][1]);
                }
            })->sum('use_elec');
            $station = Station::where('id', $val)->first();
            $temp['station_id'] = $val;
            $temp['name'] = $station['name'];
            // 累计单量
            $temp['power_total'] = $use_elec > 0 ? $use_elec / 1000 : 0;
            $data[] = $temp;
        }
        return $this->success($data);
    }
}
